--[[ 怒首领蜂1代,从mame脚本改装过来的FBNEO脚本
  作用是显示坐标中心方块和十字线
  可作为cave stg游戏的模版
  
  演示了gui显示图形和文字,memory读取数据的方法
  
  By setycyas @2025-01-30
]]

-- 这里设定基本参数
GAME = {
  -- 分辨率
  X_RESOLUTION = 240,
  Y_RESOLUTION = 320,
  -- 选择用1p还是2p
  PLAYER = "player2",
  -- 地址
  ADDRS = {
    player1 = {
      -- 横坐标纵坐标内存地址
      X_ADDR_HIGH = 0x102C94,
      X_ADDR_LOW = 0x102C95,
      Y_ADDR_HIGH = 0x102C92,
      Y_ADDR_LOW = 0x102C93,
      --散枪和激光火力等级地址
      SHOT_ADDR = 0x102CAD,
      LASER_ADDR = 0x102CAF,
    },
    player2 = {
      X_ADDR_HIGH = 0x102CD4,
      X_ADDR_LOW = 0x102CD5,
      Y_ADDR_HIGH = 0x102CD2,
      Y_ADDR_LOW = 0x102CD3,
      SHOT_ADDR = 0x102CED,
      LASER_ADDR = 0x102CEF,
    },
  },
  -- 坐标最终修正
  X_OFFSET = 0,
  Y_OFFSET = 0,
  -- 自己中心方块的半长半高,单位为原像素
  BOX_HALF_WIDTH = 2,
  BOX_HALF_HEIGHT = 2,
  -- 中心方块颜色(RGB-Alpha格式)
  BOX_BORDER_COLOR = 0xff0000FF,
  BOX_COLOR = 0xff000088,
  -- 十字线颜色
  CROSS_LINE_COLOR = 0xffffff88,
  -- 提示文字颜色
  TEXT_BORDER_COLOR = 0x000000FF,
  TEXT_COLOR = 0x00ff00FF,
}

-- 坐标变换,从内存坐标变为屏幕显示位置,返回原游戏像素,
function GAME.getX_u16()
  local player, x
  player = GAME.PLAYER
  x = memory.readword(GAME.ADDRS[player].X_ADDR_HIGH)
  
  --实际像素位置就是x的4倍可能四舍五入!最后计算屏幕比例才除以分辨率!
  x = math.floor(4.0*x/0x100)
  result = x+GAME.X_OFFSET
  
  return result
end
function GAME.getY_u16()
  local player, y
  player = GAME.PLAYER
  y = memory.readword(GAME.ADDRS[player].Y_ADDR_HIGH)
  
  --实际像素位置就是y的4倍可能四舍五入!最后计算屏幕比例才除以分辨率!
  y = math.floor(4.0*y/0x100)
  result = y+GAME.Y_OFFSET
  
  return result
end

-- 显示自机中心,x,y是原游戏坐标
function GAME.showCenter(x, y)

  -- 中心
  gui.box(
    y-GAME.BOX_HALF_HEIGHT, x-GAME.BOX_HALF_WIDTH,
    y+GAME.BOX_HALF_HEIGHT, x+GAME.BOX_HALF_WIDTH
  )
  -- 十字线
  gui.line(y, 0, y, GAME.X_RESOLUTION)
  gui.line(0, x, GAME.Y_RESOLUTION, x)
  
end

-- 监视数据显示
function GAME.check()
  local msg
  local player, shotLv, laserLv
  player = GAME.PLAYER
  shotLv = memory.readbyte(GAME.ADDRS[player].SHOT_ADDR)
  laserLv = memory.readbyte(GAME.ADDRS[player].LASER_ADDR)
  msg = string.format("SHOT = %d || LASER = %d ", shotLv, laserLv)
  
  gui.text(10, 3, msg, GAME.TEXT_COLOR, GAME.TEXT_BORDER_COLOR)
end

-- 显示模拟器信息提示
function GAME.showInfo()
  local msg
  local player, shotLv, laserLv
  player = GAME.PLAYER
  shotLv = memory.readbyte(GAME.ADDRS[player].SHOT_ADDR)
  laserLv = memory.readbyte(GAME.ADDRS[player].LASER_ADDR)
  msg = string.format("SHOT = %d || LASER = %d ", shotLv, laserLv)
  
  emu.message(msg)
end

--[[ **************************
  主函数,绑定后每一帧执行一次该函数
]]
function GAME.main_before()
  local x, y -- 坐标

  x = GAME.getX_u16()
  y = GAME.getY_u16()
  
  -- 监视数据
  GAME.check()
  -- 显示角色中心
  GAME.showCenter(x, y)
  
end

-- emu信息显示放在after较好,即使被其他信息覆盖暂停时也是能看到的
function GAME.main_after()
  
  -- 显示信息提示
  GAME.showInfo()
  
end

-- 绑定每一帧执行的函数
emu.registerbefore(GAME.main_before)
emu.registerafter(GAME.main_after)
-- 导出到全局变量
_G.game = GAME

return GAME
